﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MIMSDomain.Entities;
using Moq;
using MIMSDomain.Abstract;

namespace MIMSUnitTests.Domain
{
    [TestClass]
    public class EFBloodGroupRepositoryTests
    {
        public readonly IRepository<BloodGroup> MockBloodGroupRepository;
        
        public EFBloodGroupRepositoryTests()
        {
            //Arrange
            var _bloodGroups = new List<BloodGroup>{
                new BloodGroup{Id=1, Name="AB"},
                new BloodGroup{Id=2, Name="O"},
                new BloodGroup{Id=3, Name="A"},
                new BloodGroup{Id=4, Name="B"}
            };

            //Mock the EFBloodGroup Repository
            var target = new Mock<IRepository<BloodGroup>>();
            target.Setup(p => p.All).Returns(_bloodGroups.AsQueryable());
            target.Setup(p => p.GetById(It.IsAny<int>())).Returns((int i) =>
                _bloodGroups.Where(p => p.Id == i).Single());
            target.Setup(p => p.Save(It.IsAny<BloodGroup>())).Returns((BloodGroup objBloodGroup) =>
                {
                    if (objBloodGroup.Id.Equals(default(int)))
                    {
                        objBloodGroup.Id = _bloodGroups.Count() + 1;
                        _bloodGroups.Add(objBloodGroup);
                    }
                    else
                    {
                        var original = _bloodGroups.Where(p => p.Id == objBloodGroup.Id).Single();
                        if (original == null)
                        {
                            return false;
                        }
                        original.Name = objBloodGroup.Name;
                    }
                    return true;
                });
            target.Setup(p => p.Delete(It.IsAny<BloodGroup>())).Returns((BloodGroup objBloodGroup) =>
                {

                    if (_bloodGroups.Contains(objBloodGroup))
                    {
                        _bloodGroups.Remove(objBloodGroup);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            
            MockBloodGroupRepository = target.Object;
        }
        
        [TestMethod]
        public void CanSaveBloodGroup()
        {
            //Arrange
            var count = MockBloodGroupRepository.All.Count();
            //Assert
            Assert.AreEqual(4, count); //Confirm blood group count before saving
            //Act
            var expected = MockBloodGroupRepository.Save(new BloodGroup{ Name= "AB+" });

            //Assert
            count = MockBloodGroupRepository.All.Count();
            Assert.AreEqual(5, count); //Confirm blood group count after saving

        }

        [TestMethod]
        public void CannotAddDuplicateBloodGroup()
        {
            throw new NotImplementedException();
        }

        [TestMethod]
        public void CanGetBloodGroupById()
        {
            //Act
            var expected = MockBloodGroupRepository.GetById(3);
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected,typeof(BloodGroup));
            Assert.AreEqual(expected.Name,"A");
        }

        [TestMethod]
        public void CanGetAllBloodGroups()
        {
            //Act
            var expected = MockBloodGroupRepository.All;
            //Assert
            Assert.IsNotNull(expected);
            Assert.IsInstanceOfType(expected, typeof(IQueryable<BloodGroup>));
            Assert.AreEqual(expected.Count(), 4);
        }

        [TestMethod]
        public void CanDeleteBloodGroup()
        {
            //Arrange
            var count = MockBloodGroupRepository.All.Count();
            Assert.AreEqual(4, count);
            var objBloodGroup = MockBloodGroupRepository.GetById(3);
            Assert.IsInstanceOfType(objBloodGroup, typeof(BloodGroup));
            //Act
            MockBloodGroupRepository.Delete(objBloodGroup);
            count = MockBloodGroupRepository.All.Count();
            //Assert
            Assert.AreEqual(3, count);
        }
    }
}
